import gtk,gobject
import WindowTemplate
import Locations
import Shares

class ShareWindow(WindowTemplate.WindowTemplate):
    """The share add/edit window"""
    
    def __init__(self,controller,share=None):
        """constuctor"""
        
        WindowTemplate.WindowTemplate.__init__(self,controller)
        self.share = share       # if edit mode this is the location to edit
        self.ddl_protocol_display_text = self.config.display_text['ddl protocol']
        self.create_window()    
        
        if self.share:
            self.fill()
        else:
            # Mount point autocompletion
            self.tb_name.connect("changed", self.name_changed_callback)
            self.tb_mount_point.set_text(self.config.user['DEFAULT MOUNT POINT'] + self.__get_location().name + '/' + self.tb_name.get_text())
            self.tb_mount_point_got_focus = False
            self.tb_mount_point_callback = self.tb_mount_point.connect("focus-in-event", self.mount_point_got_focus_callback)
            # Port
            self.tb_port.set_text(str(self.config.glob['PORT'][self.__get_protocol()]))
        
        self.locations.connect('add',self.update_ddl_location)      #\
        self.locations.connect('set',self.update_ddl_location)      #-update ddl location on locations changes
        self.locations.connect('remove',self.update_ddl_location)   #/
        
    def create_window(self):
        '''create and add widgets to the window'''
        
        if self.share:
            self.set_title("Share Settings")
        else:
            self.set_title("New Share")
        
        self.global_vbox = gtk.VBox(False,5)
        self.add(self.global_vbox)
        
        notebook = gtk.Notebook()
        self.global_vbox.pack_start(notebook)
        notebook.append_page(self.create_main_page(),gtk.Label("Share"))
        notebook.append_page(self.create_advanced_page(),gtk.Label("Advanced"))
        
        #Automount
        self.cb_automount = gtk.CheckButton("Automount")
        self.global_vbox.pack_start(self.cb_automount)
        
        #Bottom Button
        try_btn = gtk.Button("Try")
        try_btn.connect("clicked", self.try_callback)
        submit_btn = gtk.Button(None,gtk.STOCK_APPLY)
        submit_btn.connect("clicked",self.submit)
        self.global_vbox.pack_end(self.build_hbox((try_btn,submit_btn)),False)
        
        self.show_all()
    
    def create_main_page(self):
        self.main_page_vbox = gtk.VBox(False,5)
        self.lbl_protocol = gtk.Label("Protocol :")
        self.ddl_protocol = gtk.combo_box_new_text()
        for protocol in self.config.glob['PROTOCOLS']:
            self.ddl_protocol.append_text(self.ddl_protocol_display_text[protocol])
        self.__set_protocol()
        self.ddl_protocol.connect('changed',self.protocol_changed_callback)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_protocol,self.ddl_protocol)))
        
        #Name
        self.lbl_name = gtk.Label("Name :")
        self.tb_name = gtk.Entry(max=25)
        self.add_validator(self.tb_name,'REGEX_NAME',False)
        self.set_focus(self.tb_name)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_name,self.tb_name)))
        
        #Location (Drop Down List)
        self.lbl_location = gtk.Label("Location :")
        self.create_location_combo_box()
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_location,self.ddl_locations))) 
        
        #Mount point
        self.lbl_mount_point = gtk.Label("Mount_Point :")
        self.tb_mount_point = gtk.Entry()
        self.add_validator(self.tb_mount_point,'REGEX_MOUNT_POINT',False)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_mount_point,self.tb_mount_point)))

        #Server
        self.lbl_server = gtk.Label("Server :")
        self.tb_server = gtk.Entry()
        self.add_validator(self.tb_server,'REGEX_NAME',False)       
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_server,self.tb_server)))
        
        #Path
        self.lbl_path = gtk.Label("Path :")
        self.tb_path = gtk.Entry()
        self.add_validator(self.tb_path,'REGEX_PATH',False)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_path,self.tb_path)))
        
        #Domain
        self.lbl_domain = gtk.Label("Domain :")
        self.tb_domain = gtk.Entry() 
        self.add_validator(self.tb_domain,'REGEX_DOMAIN',True)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_domain,self.tb_domain)))
        
        #Login
        self.lbl_login = gtk.Label("Login :") 
        self.tb_login = gtk.Entry()
        self.add_validator(self.tb_login,'REGEX_LOGIN',True) 
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_login,self.tb_login)))
        
        #Password
        self.lbl_password = gtk.Label("Password :")
        self.tb_password = gtk.Entry()
        self.tb_password.set_visibility(False)
        self.add_validator(self.tb_password,'REGEX_PASSWORD',True)
        self.main_page_vbox.pack_start(self.build_hbox((self.lbl_password,self.tb_password)))
        
        return self.main_page_vbox
    
    def create_advanced_page(self):
        self.advanced_page_vbox = gtk.VBox(False,5)
        self.lbl_port = gtk.Label("Port :")
        self.tb_port = gtk.Entry()
        self.add_validator(self.tb_port,'REGEX_PORT',True)
#        self.add_numeric_validator
        self.advanced_page_vbox.pack_start(self.build_hbox((self.lbl_port,self.tb_port)))
        return self.advanced_page_vbox
    
    def create_location_combo_box(self):
        '''create the location sorted combo box with an hidden column to store the location id'''
        
        # Listmodel
        self.listmodel = gtk.ListStore( gobject.TYPE_INT, gobject.TYPE_STRING )
        self.fill_listmodel()
        
        # Sorted listmodel
        self.treemodelsort = gtk.TreeModelSort(self.listmodel)
        self.treemodelsort.set_sort_func(999, self.sort_treemodel)
        self.treemodelsort.set_sort_column_id(999,gtk.SORT_ASCENDING)
#        self.treemodelsort.set_sort_column_id(1,gtk.SORT_ASCENDING)
        
        # Cell renderer
        cr_name = gtk.CellRendererText()
        # Drop Down List
        self.ddl_locations = gtk.ComboBox(self.treemodelsort)
        self.ddl_locations.pack_start(cr_name, True)
        self.ddl_locations.add_attribute(cr_name, 'text',1)
        self.__set_location()
    
    def sort_treemodel(self, model, iter1, iter2):
        item1 = model.get_value(iter1,1)
        id_item1 = model.get_value(iter1,0)
        
        if not item1:
            return -1
        else:
            item1 = item1.lower()
        
        item2 = model.get_value(iter2,1)
        id_item2 = model.get_value(iter2,0)
        
        if not item2:
            return 1
        else:
            item2 = item2.lower()
        
        # Everywhere en 1er
        if id_item1 == 0:
            return -1
        if id_item2 == 0:
            return 1
        
        # Curr loc en 2eme
        if self.config.network['CURRENT LOCATION']:
            if id_item1 == self.config.network['CURRENT LOCATION'].id:
                return -1
            if id_item2 == self.config.network['CURRENT LOCATION'].id:
                return 1
        
        # tri alphabetique pour la suite
        if item1 < item2 :
            return -1
        elif item1 > item2 :
            return 1
        else:
            return 0
    
    def __get_protocol(self):
        '''return the protocol selected value'''
        ddl_text = self.ddl_protocol.get_active_text()
        for key,value in self.ddl_protocol_display_text.iteritems():
            if value == ddl_text:
                return key
        
    def __set_protocol(self,protocol=None):
        '''set the protocol ddl'''
        
        self.ddl_protocol.set_active(0)
        if protocol:
            model = self.ddl_protocol.get_model()
            iter = model.get_iter_root()
            while iter != None:
                if model.get_value(iter,0) == self.ddl_protocol_display_text[protocol]:
                    self.ddl_protocol.set_active_iter(iter)
                    break
                iter = model.iter_next(iter)
        
    def __get_location(self):
        '''return the location selected in the location ddl'''
        
        location_id = self.ddl_locations.get_model().get_value(self.ddl_locations.get_active_iter(),0)
        return self.locations[location_id]
    
    def __set_location(self,location=None):
        '''set the location ddl'''
        
        self.ddl_locations.set_active(0)
        if location:
            iter = self.listmodel.get_iter_root()
            while iter != None:
                if self.listmodel.get_value(iter,0) == location.id:
                    self.ddl_locations.set_active_iter(self.treemodelsort.convert_child_iter_to_iter(None,iter))
                    break
                iter = self.listmodel.iter_next(iter)
    
    def __get_port(self):
        port = self.tb_port.get_text() 
        if port == "":
            return self.config.glob['PORT'][self.__get_protocol()]
        else:
            return int(port)
    
    def fill_listmodel(self):
        '''clear then fill the location ddl listmodel'''
        
        self.listmodel.clear()
        for location_id,location in self.locations:
            self.listmodel.append((location_id,location.name))
    
    def update_ddl_location(self,*args):
        '''refill then try to re-set the ddl location'''
        
        self.fill_listmodel()
        if self.share:
            self.__set_location(self.share.location)
        else:
            self.__set_location()
        
    def protocol_changed_callback(self,*args):
        '''protocol ddl cahanged callback, show/hide the right fields and enable/disable validators'''
        
        # mettre les champs associs au protocol qqpart ??
        protocol = self.__get_protocol()
        if protocol == "NFS":
            for item in (self.lbl_domain,self.tb_domain,self.lbl_login,self.tb_login,self.lbl_password,self.tb_password):
                item.hide()
                if isinstance(item,gtk.Entry):
                    self.disable_validator(item)
        elif protocol in ("SSH","FTP"):
            for item in (self.lbl_domain,self.tb_domain):
                item.hide()
                if isinstance(item,gtk.Entry):
                    self.disable_validator(item)
            for item in (self.lbl_login,self.tb_login,self.lbl_password,self.tb_password):
                item.show()
                if isinstance(item,gtk.Entry):
                    self.enable_validator(item)
        elif protocol == "SAMBA":
            for item in (self.lbl_domain,self.tb_domain,self.lbl_login,self.tb_login,self.lbl_password,self.tb_password):
                item.show()
                if isinstance(item,gtk.Entry):
                    self.enable_validator(item)
        
        self.tb_port.set_text(str(self.config.glob['PORT'][protocol]))
            
    def mount_point_got_focus_callback(self,*args):
        self.tb_mount_point_got_focus = True
        self.tb_mount_point.disconnect(self.tb_mount_point_callback)
        
    def name_changed_callback(self,*args):
        if not self.tb_mount_point_got_focus :
            self.tb_mount_point.set_text(self.config.user['DEFAULT MOUNT POINT'] + self.__get_location().name + '/' + self.tb_name.get_text().replace(' ', '_'))
    
    def fill(self):
        '''fill all the fields and set the ddls for the edited share'''
        
        self.tb_name.set_text(self.share.name)
        self.tb_mount_point.set_text(self.share.mount_point)
        self.tb_server.set_text(self.share.server)
        self.tb_path.set_text(self.share.path)
        self.cb_automount.set_active(self.share.automount)
        self.tb_domain.set_text(self.share.domain)
        self.tb_login.set_text(self.share.login)
        self.tb_password.set_text(self.share.password)
        self.__set_protocol(self.share.protocol)
        self.__set_location(self.share.location)
        if self.share.port:
            self.tb_port.set_text(str(self.share.port))
            
    def try_callback(self,*args):
        print "Not implemented Yet"
#        if self.is_valid():
#            share = Shares.Share(0)
#            share.mount_point = '/tmp/miam/try'
#            share.server = self.tb_server.get_text()
#            share.path = self.tb_path.get_text()
#            share.login = self.tb_login.get_text()
#            share.password = self.tb_password.get_text()
#            share.domain = self.tb_domain.get_text()
#            share.protocol = self.__get_protocol()
#            share.port = self.__get_port()
#            
#            import Exceptions
#            try:
#                if self.controller.test_share(share):
#                    print 'You Win'
#                    
#            except Exceptions.ConnexionFailed,e:
#                print e
#            
#            except Exceptions.SharePathUnreachable,e:
#                print e
#            
#            except Exceptions.PermissionDenied,e:
#                print e
#                
#            except Exception,e:
#                print e

    def submit(self,*args):
        '''submit button callback, check if is valid, create or edit share, set/add the share'''
        
        if self.is_valid():
                if not self.share:
                    if not (self.tb_server.get_text(),self.tb_path.get_text(),self.__get_protocol()) in [(share[1].server,share[1].path,share[1].protocol) for share in self.controller.shares]:
                        self.share = Shares.Share(self.shares.get_id())
                    else:
                        import Dialog
                        title = 'Share already exist'
                        msg = '%s on %s already exist in share list' % (self.tb_path.get_text(),self.tb_server.get_text())
                        Dialog.InfoDialog(title,msg,self).run()
                        return False
                
                if self.share.server != self.tb_server.get_text() or self.share.protocol != self.__get_protocol():
                    self.share.latency = None
                self.share.name = self.tb_name.get_text()
                self.share.mount_point = self.tb_mount_point.get_text().rstrip('/')
                self.share.server = self.tb_server.get_text()
                self.share.path = self.tb_path.get_text()
                if self.share.protocol == 'SAMBA':
                    self.share.path = self.share.path.lstrip('/')
                self.share.login = self.tb_login.get_text()
                self.share.password = self.tb_password.get_text()
                self.share.domain = self.tb_domain.get_text()
                self.share.automount = self.cb_automount.get_active()
                self.share.protocol = self.__get_protocol()
                self.share.location = self.__get_location()
                self.share.port = self.__get_port()
                self.shares[self.share.id] = self.share # this cause Shares emit the set or add signal
                self.close()